#ifndef _WS_HPP
#define _WS_HPP

#define TAG "WS.H"

void wsInit();
void wsStart();
void wsEvent(void *args, esp_event_base_t base, int32_t id, void *data);
static esp_websocket_client_handle_t *getWsHandle(char *url, char *chan, int port);
void wsReStart();
static void wsGetStr(esp_websocket_event_data_t *data);
void wsGetBin(char *data, int len, int payloadLen);

void wsSendOp();

void wsInitTask() {
	pageInfoAdd("Init WebSockets...");
	wsHandle = getWsHandle(wsUrl, wsChannel, wsPort);
	wsStart();
	vTaskDelete(NULL);
}

static esp_websocket_client_handle_t *getWsHandle(char *url, char *chan, int port) {
	char *wsUri[100] = {0};
	sprintf(wsUri, "%s/%s", url, chan);
	const esp_websocket_client_config_t wsCfg = 
	{
		.uri = wsUri,
		.port = port,
		.disable_auto_reconnect = false,
		.keep_alive_enable = true,
	};
	return esp_websocket_client_init(&wsCfg);
}

void wsStart() {
	ESP_ERROR_CHECK(esp_websocket_register_events(wsHandle, WEBSOCKET_EVENT_ANY, wsEvent, NULL));
	ESP_ERROR_CHECK(esp_websocket_client_start(wsHandle));
}

void wsReStart() {
	ESP_ERROR_CHECK(esp_websocket_client_start(wsHandle));
}

void wsSendOp() {
	uint32_t bit;
	while(1) {
		xTaskNotifyWait(
			0x00,
			ULONG_MAX,
			&bit,
			portMAX_DELAY
		);
		if((bit & BIT0) != 0)
		{
			char *msg[1024] = {0};
			strcat(msg, stCallSign);
			strcat(msg, "|");
			strcat(msg, inputCode);
			esp_websocket_client_send_text(wsHandle, msg, strlen(msg), 0);
			strcpy(inputCode, "");
			pageHomeCleanInput();
		}
		if((bit & BIT1) != 0)
		{

		}
		vTaskDelay(pdMS_TO_TICKS(50));
	}
	vTaskDelete(NULL);
}


void wsEvent(void *args, esp_event_base_t base, int32_t id, void *eventData) {
	esp_websocket_event_data_t *data = (esp_websocket_event_data_t *)eventData;
	switch(id) {
		case WEBSOCKET_EVENT_CONNECTED:
			// printf("ws connected.\n");
			pageInfoAdd("WebSockets connected.");
			xEventGroupSetBits(eventGroup, EVENT_WS_CONNECTED);
			break;
		
		case WEBSOCKET_EVENT_DISCONNECTED:
			// printf("ws disconnected!!!!!\n");
			xEventGroupSetBits(eventGroup, EVENT_WS_DISCONNECTED);
			// vTaskDelay(pdMS_TO_TICKS(3000));
			// wsReStart();

			break;
		
		case WEBSOCKET_EVENT_DATA:
			if((int)data->op_code == 1) {
				wsGetStr(data);
			}
			break;
			// ESP_LOGI(TAG, "WEBSOCKET_EVENT_DATA");
			// ESP_LOGI(TAG, "Received opcode=%d", data->op_code);
			// if (data->op_code == 0x08 && data->data_len == 2) {
			// 	ESP_LOGW(TAG, "Received closed message with code=%d", 256*data->data_ptr[0] + data->data_ptr[1]);
			// } else {
			// 	ESP_LOGW(TAG, "Received=%.*s", data->data_len, (char *)data->data_ptr);
			// }
			// ESP_LOGW(TAG, "Total payload length=%d, data_len=%d, current payload offset=%d\r\n", data->payload_len, data->data_len, data->payload_offset);
		
		case WEBSOCKET_EVENT_ERROR:
			// printf("ws failed.\n");
			pageInfoAdd("WebSockets failed.");
			break;

		case WEBSOCKET_EVENT_CLOSED:
			// printf("ws closed.\n");
			break;

		default :
			printf("id = %d\n", id);
			break;
	}
}


static void wsGetStr(esp_websocket_event_data_t *data) {
	char *getStr = malloc(data->data_len + 1);
	sprintf(getStr, "%.*s", data->data_len, (char *)data->data_ptr);
	xQueueSendToBack(wsDataQ, &getStr, 0);

	/* // 测试
	char *myData = "helloWorld";
	char *myItem = malloc(strlen(myData)+1); 
	strcpy(myItem, myData);
	printf("str = %s\n", myItem);
	xQueueSendToBack(wsDataQ, &myItem, 0); */

}


void wsGetBin(char *data, int len, int payloadLen) {
	// printf("ws got BIN data = %s, len = %d, payloadLen = %d\n", data, len, payloadLen);
}



#endif